package net.child.chess.pieces;

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import net.child.chess.utils.ChessDef;
import net.child.chess.utils.Position;
import net.child.chess.utils.Move;

public abstract class Piece 
{
	public enum Type
	{
		KING,
		QUEEN,
		ROOK,
		BISHOP,
		KNIGHT,
		POWN,
	};
	
	public Piece(ChessDef.Color color,Type type, PieceState state, int imageId)
	{
		mColor = color;
		mType = type;
		mState = new PieceState(state);
		mImageId = imageId;
	}

	public ChessDef.Color color()
	{
		return mColor;
	}
	
	public int imageId()
	{
		return mImageId;
	}
	
	public Type type()
	{
		return mType;
	}
	
	public Position position()
	{
		return mState.position();
	}
	
	public void move(int pos)
	{
		mState.move(pos);
	}
	
	//	in some cases like castling, it is needed extra move, the following
	//	function provide interface to the piece to determine that another move is needed.
	public Move getExtraMove(IMoves iMoves)
	{
		return null;
	}
	
	public abstract void attacks(List<Integer> squares, IMoves iMoves);
	
	public void moves(List<Integer> squares, IMoves iMoves)
	{
		List<Integer> attackedSquares = new ArrayList<Integer>();
		attacks(attackedSquares, iMoves);
		Iterator<Integer> attackedSquaresIter = attackedSquares.iterator();
		while(attackedSquaresIter.hasNext())
		{
			int toPosition = attackedSquaresIter.next();
			if(iMoves.isValidMove(this, toPosition))
			{
				squares.add(toPosition);
			}
		}
	}
	
	//	only the "pown" could be promoted in several cases.
	public boolean shouldBePromoted() 
	{
		return false;
	}
	
	public void restoreState(PieceState state)
	{
		mState.restoreState(state);
	}
	
	public PieceState state()
	{
		return mState;
	}
	
	public boolean wasMoved()
	{
		return mState.wasMoved();
	}
	
	protected void addAttackIfValid(List<Integer> squares, int to, IMoves iMoves)
	{
		if(iMoves.isOpponentSquare(color(), to) || iMoves.isEmptySquare(to))
		{
			squares.add(to);
		}
	}
	
	protected void addMoveIfValid(List<Integer> squares, int to, IMoves iMoves)
	{
		if(iMoves.isValidMove(this, to))
		{
			squares.add(to);
		}
	}
	
	private ChessDef.Color mColor;
	private Type mType;
	private PieceState mState;
	private int mImageId;
}
